package com.fingard.dsp.bank.directbank.chinaums01;

import com.alibaba.fastjson.JSON;
import com.fingard.constant.Format;
import com.fingard.crypto.SignVerifyHelper;
import com.fingard.dsp.bank.directbank.VerifyState;
import com.fingard.dsp.bank.directbank.bankInterface.IAuthentication;
import com.fingard.dsp.bank.reqrespobj.auth.ReqAuth;
import com.fingard.dsp.bank.reqrespobj.auth.ReqQryAuth;
import com.fingard.dsp.bank.reqrespobj.auth.RetAtsAuth;
import com.fingard.dsp.bank.reqrespobj.auth.detail.RetAtsAuthDetail;
import com.fingard.text.StringHelper;

import net.sf.json.JSONObject;

import java.util.Date;

/**
 * 银联鉴权
 * 
 * @author fanghh
 * @date 2018/7/18
 */
public class ChinaUMS01Authentication extends ChinaUMS01Base implements IAuthentication {
    @Override
    public RetAtsAuth dealAuth(ReqAuth p_reqAuth) throws Exception {
        RetAtsAuth retAts = new RetAtsAuth(p_reqAuth.reqHeader);
        RetAtsAuthDetail tmpRetDetail = new RetAtsAuthDetail();

        try {
            String appId = getBankConfig().getValueAsString("appId");
            if (StringHelper.isNullOrEmpty(appId)) {
                WriteBankLogLn2("appId为空，请检查config.xml配置...");
            }

            String appKey = getBankConfig().getValueAsString("appKey");
            if (StringHelper.isNullOrEmpty(appKey)) {
                WriteBankLogLn2("appKey为空，请检查config.xml配置...");
            }

            String timestamp = Format.DateTime14Format.format(new Date());
            String nonce = get_nonce_str();

            String signData = appId + timestamp + nonce + appKey;
            WriteBankLogLn2("accessToken获取签名原始数据:" + signData);

            // accsess获取请求JSON
            JSONObject json = new JSONObject();
            json.put("appId", appId);
            json.put("timestamp", timestamp);
            json.put("nonce", nonce);
            json.put("signature", new String(SignVerifyHelper.sha1X16(signData, getCharset()), getCharset()));

            String postTokenStr = JSON.toJSONString(json);
            WriteBankLogLn2("accessToken获取post请求数据:" + postTokenStr);

            String postTokenUrl = bankFront.getUrl("getAccessToken");
            WriteBankLogLn2("accessToken获取服务地址:" + postTokenUrl);

            String tmpStrRet = post(postTokenUrl, postTokenStr, null, false);
            WriteBankLogLn2("获取accessToken响应数据:" + tmpStrRet);
            
            if (StringHelper.hasAnyChar(tmpStrRet)) {
                if (tmpStrRet.contains("{")) {
                    JSONObject respJson = JSONObject.fromObject(tmpStrRet);

                    if ("0000".equals(respJson.getString("errCode"))) {
                        String accessToken = respJson.getString("accessToken");
                        WriteBankLogLn2("accessToken获取成功,值为:" + accessToken);

                        String authStr = "OPEN-ACCESS-TOKEN AccessToken=" + accessToken + "";

                        // 卡认证请求JSON
                        JSONObject cardInfoJSON = new JSONObject();

                        if (StringHelper.hasAnyChar(p_reqAuth.authDetail.authAct)) {
                        	cardInfoJSON.put("cardNo", p_reqAuth.authDetail.authAct);
                        }
                        
                        if (StringHelper.hasAnyChar(p_reqAuth.authDetail.authName)) {
                        	cardInfoJSON.put("name", p_reqAuth.authDetail.authName);
                        }
                        
                        cardInfoJSON.put("personalMandate", "1");
//                        cardInfoJSON.put("CVN2", "");
//                        cardInfoJSON.put("cardExpire", "");
                        
                        /*
                         * 证件号和证件类型必须两个同时输入或者两个都不输
                         */
                        if (StringHelper.hasAnyChar(p_reqAuth.authDetail.certNum)) {
                        	cardInfoJSON.put("certType", getBankConfig().getMapValueByKey("certTypeTokenMapping", p_reqAuth.authDetail.certType));
                        	cardInfoJSON.put("certNo", p_reqAuth.authDetail.certNum);
                        }
                        
                        if (StringHelper.hasAnyChar(p_reqAuth.authDetail.cellPhone)) {
                        	cardInfoJSON.put("phoneNo", p_reqAuth.authDetail.cellPhone);
                        }

                        JSONObject postJSON = new JSONObject();
                        postJSON.put("data", JSON.toJSONString(cardInfoJSON));

                        String postRealAuthData = JSON.toJSONString(postJSON);
                        WriteBankLogLn2("卡认证交易请求JSON:" + postRealAuthData);

                        String realAuthSubmitUrl = bankFront.getUrl("realAuthSubmit");
                        WriteBankLogLn2("卡认证交易服务地址:" + realAuthSubmitUrl);

                        tmpStrRet = post(realAuthSubmitUrl, postRealAuthData, authStr, true);
                        WriteBankLogLn2("卡认证交易响应数据:" + tmpStrRet);
                        
                        if (StringHelper.hasAnyChar(tmpStrRet)) {
                            if (tmpStrRet.contains("{")) {
                                JSONObject cardVerifyRet = JSONObject.fromObject(tmpStrRet);

                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.respInfo = cardVerifyRet.getString("errInfo");
                                tmpRetDetail.reqSeqID = p_reqAuth.authDetail.askNumber;

                                if ("0000".equals(cardVerifyRet.getString("errCode"))) {
                                	String tmprspData = cardVerifyRet.getString("data");
                                	if (StringHelper.hasAnyChar(tmprspData)) {
                                		JSONObject detailDataResp = JSONObject.fromObject(tmprspData);

                                        String tmpRespCode = detailDataResp.getString("respCode");
                                        if ("00".equals(tmpRespCode)) {
                                            tmpRetDetail.verifyState = VerifyState.SUCCESS;
                                        } else {
                                            tmpRetDetail.verifyState = VerifyState.FAIL;
                                            tmpRetDetail.failType = getBankConfig().getMapValueByKey("failTypeMapping", detailDataResp.getString("detailRespCode"));
                                        }
                                        tmpRetDetail.originalCode = StringHelper.joinNotEmpty("+", tmpRespCode, detailDataResp.getString("detailRespCode"));
                                        tmpRetDetail.originalInfo = detailDataResp.getString("detailRespMsg");
                                        tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("AuthMapping", detailDataResp.getString("detailRespCode"));
                                        tmpRetDetail.unifiedInfo = detailDataResp.getString("detailRespMsg");
                                        tmpRetDetail.respInfo = detailDataResp.getString("detailRespMsg");
                                	} else {
                                		tmpRetDetail.respCode = "-1";
                                        tmpRetDetail.respInfo = cardVerifyRet.getString("resultInfo");
                                	}
                                } else {
                                    tmpRetDetail.respCode = "-1";
                                    tmpRetDetail.respInfo = cardVerifyRet.getString("errInfo");
                                }
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "卡认证交易银行响应数据格式非法";
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "卡认证交易银行响应为空";
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = "获取accessToken失败,原因:" + respJson.getString("errInfo");
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "获取accessToken时银行响应数据格式非法";
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "获取accessToken时银行响应为空";
            }
        } catch (Exception e) {
            e.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = e.getMessage();
            WriteBankLogLn(e);
        }

        if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_reqAuth.authDetail.askNumber;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsAuth dealQryAuth(ReqQryAuth p_reqAuth) throws Exception {
        RetAtsAuth retAts = new RetAtsAuth(p_reqAuth.reqHeader);
        RetAtsAuthDetail tmpRetDetail = new RetAtsAuthDetail();

        tmpRetDetail.respCode = "-1";
        tmpRetDetail.respInfo = "暂不支持此交易类型:" + p_reqAuth.reqHeader.transType;

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }
}
